package com.io.aop;

import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONUtil;
import com.io.vo.ApiResult;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.StopWatch;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

/**
 * 请求记录
 *
 * @author 郭冬冬
 * @version 1.0
 */
@Aspect
@Component
@Slf4j
public class HttpAspect {
    // 所有的controller
    @Pointcut(
            "execution(public * com.io.controller..*Controller.*(..))"
            + "&&!execution(public * com.io..*Web.*(..))"
    )
    public void pointcutController() {
    }

    // Spring 环绕通知 切点
    @Around("pointcutController()")
    public Object aroundHttp(ProceedingJoinPoint pjp) throws Throwable {
        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
        Assert.notNull(sra, "请求不能为空！");
        HttpServletRequest request = sra.getRequest();
        String url = request.getRequestURL().toString();
        String method = request.getMethod();
        String uri = request.getRequestURI();
        // 获取get的请求地址
        String getParams = request.getQueryString();
        // 获取post的请求参数
        String postParams = JSONUtil.toJsonStr(Arrays.toString(pjp.getArgs()));
        log.info("======================start======================");
        log.info("请求开始===>请求的URL:[{}],各个参数:[{}],请求方法:[{}],请求的URI[{}]", url, postParams, method, uri);
        StopWatch watch = new StopWatch(IdUtil.randomUUID());
        watch.start();
        Object result;
        ApiResult j;
        result = pjp.proceed();
        j = (ApiResult) result;
        watch.stop();
        log.info("请求结束===>执行时间:[{}],Controller返回值:[{}]", watch, JSONUtil.toJsonStr(j));
        log.info("======================end======================");
        return j;
    }
}